from audioop import reverse

from django.http import JsonResponse
from django.shortcuts import render,redirect
from django.views import View
from django.views.decorators.csrf import csrf_exempt

from utils.encrypt import uid
from utils.tencent.cos import upload_file
from web import models
from web.forms.wiki import WikiModelForm


def wiki(request,project_id):
    """ wiki的首页 """
    # 后边有?wiki_id=6就证明你是正在拿wiki文档详细
    wiki_id = request.GET.get('wiki_id')
    # isdecimal判断是否只有十进制数是为了防止爬虫这样传?wiki_id=asd，查询语句id=asd就会报错
    # 如果查询参数没有待wiki_id，说明你不想看详细，直接放回wiki主页
    if not wiki_id or not wiki_id.isdecimal():
        return render(request, 'wiki.html')
    # 如果带了就把这个wiki详细对象传过去
    wiki_object = models.Wiki.objects.filter(id=wiki_id, project_id=project_id).first()

    return render(request, 'wiki.html', {'wiki_object': wiki_object})


class WikiAdd(View):
    """wiki文档添加"""
    def get(self,request,project_id):
        form = WikiModelForm(request)
        return render(request,'wiki_form.html',{'form':form})

    def post(self,request,project_id):
        form = WikiModelForm(request,request.POST)
        if form.is_valid():
            # 判断用户是否已经选择父文章
            if form.instance.parent:
                form.instance.depth = form.instance.parent.depth + 1
            else:
                form.instance.depth = 1
            # 项目id我们表里有但没有让用户填，得手动加进instance进库
            form.instance.project=request.tracer.project
            form.save()
            # 不知道为啥reverse报错
            # url = reverse('wiki',kwargs={'project_id':project_id})
            return redirect('/manage/{}/wiki'.format(project_id))

        return render(request, 'wiki_form.html', {'form': form})


def wiki_catalog(request,project_id):
    """展示wiki文档目录"""

    # 获取当前项目所有的wiki文档目录: data = QuerySet类型
    data = models.Wiki.objects.filter(project=request.tracer.project).values("id", 'title', 'parent_id').order_by(
        'depth', 'id')
    # 必须list抓换一下，要不然JsonResponse默认调用的dumps会报错，序列化不了queryset
    return JsonResponse({'status': True, 'data': list(data)})


def wiki_delete(request, project_id, wiki_id):
    """ 删除文章 """
    # 一定要做当前文档判断，不然你就删人家的了project_id=project_id
    models.Wiki.objects.filter(project_id=project_id, id=wiki_id).delete()

    # 返回到wiki列表里，肯定要project_id撒，你要知道在那个项目里操作wiki文档
    # url = reverse('wiki', kwargs={'project_id': project_id})
    return redirect('/manage/{}/wiki'.format(project_id))

def wiki_edit(request, project_id, wiki_id):
    """ 编辑文章 """
    # 拿到要编辑的文章对象
    wiki_object = models.Wiki.objects.filter(project_id=project_id, id=wiki_id).first()
    # 如果该项目下根本没有wiki_id这篇文档直接回到wiki页面
    if not wiki_object:
        # return redirect('/manage/{}/wiki'.format(project_id))
        # 等同于
        url = reverse('wiki', kwargs={'project_id': project_id})
        return redirect(url)
    # 如果带了wiki_id且的确存在就判断请求方式，get方法就展示出详情，post就是编辑提交
    if request.method == "GET":
        # 如果 instance 有对象则是修改数据 没有就是 新增数据,必须传入对应模型类的form组件
        form = WikiModelForm(request,instance=wiki_object)
        return render(request, 'wiki_form.html', {'form': form})
    # 如果是post请求
    form = WikiModelForm(request, data=request.POST, instance=wiki_object)
    if form.is_valid():
        if form.instance.parent:
            form.instance.depth = form.instance.parent.depth + 1
        else:
            form.instance.depth = 1
        form.save()
        # 编辑成功后既不要跳转到wiki页面了，跳到wiki/detail?wiki_id=2
        preview_url = "/manage/{0}/wiki?wiki_id={1}".format(project_id, wiki_id)
        return redirect(preview_url)

    return render(request, 'wiki_form.html', {'form': form})


# 因为编写wiki文档时，我是ajax发请求,我就不去修改markdown的js'源码，让它带上csrf，这儿直接免除即可
@csrf_exempt
def wiki_upload(request, project_id):
    """ markdown插件上传图片 """
    print("收到前端markdown的自带js发来的图片")
    # 先初始化返回给前端markdown的json数据，定死的形识
    result = {
        'success': 0,
        'message': None,
        'url': None
    }
    # print(request.FILES)  # 你会发现是editormd-image-file这样的一个键
    image_object = request.FILES.get('editormd-image-file')
    if not image_object:
        result['message'] = "文件不存在"
        return JsonResponse(result)

    # 拿到上传文件名的后缀名
    ext = image_object.name.rsplit('.')[-1]
    # 生成一个随机的文件名
    key = "{}.{}".format(uid(request.tracer.user.mobile_phone), ext)
    # 把cos上传文件封装到upload_file中，里面还有一个为创建桶封装的create_bucket
    image_url = upload_file(
        request.tracer.project.bucket,  # 项目在cos中的桶名
        request.tracer.project.region,  # 项目在cos的区域
        image_object,  # 上传的对象
        key   # 上传的文件名
    )

    print("上传成功！ ！" + image_url) # 检验是否upload_file函数给我上传成功

    # 通知前端markdown,我这上传成功了(markdown的固定通知格式)
    result['success'] = 1
    result['url'] = image_url
    return JsonResponse(result)